package com.ruoyi.common.utils.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;


public class DateUtil {
	public static final String DATE_TIME_FORMAT_COMPACT = "yyyyMMddHHmmss";
	public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String DATE_FORMAT = "yyyy-MM-dd";
	public static final String DATE_FORMAT_MONTH = "MM-dd";
	public static final String DATE_FORMAT_MINUTE = "yyyy年MM月dd日HH:mm分";
	public static final String DATE_TIME_FORMAT_MILLISECOND = "yyyy-MM-dd HH:mm:ss.SSS";

	public DateUtil() {
	}

	public static Date getBirthdayByAge(Integer age) {
		SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
		try {
			if(age == null) {
				return format.parse(format.format(new Date()));
			}
			Calendar cal = Calendar.getInstance();
			int day = cal.get(Calendar.DATE);
			int month = cal.get(Calendar.MONTH) + 1;
			int year = cal.get(Calendar.YEAR);
			int r = year-age;
			String dat = r+"-"+month+"-"+day;
			return format.parse(dat);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return new Date();
	}


	public static LocalDate dateToLocalDate(Date date){
		Instant instant = date.toInstant();
		ZoneId zoneId = ZoneId.systemDefault();

		LocalDate localDate = instant.atZone(zoneId).toLocalDate();
		return localDate;
	};

	public static LocalDateTime dateToLocalDateTime(Date date){
		Instant instant = date.toInstant();
		ZoneId zoneId = ZoneId.systemDefault();

		LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
		return localDateTime;
	};

	//LocalDate -> Date
	public static Date asDate(LocalDate localDate) {
		return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
	}

	//LocalDateTime -> Date
	public static Date asDate(LocalDateTime localDateTime) {
		return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
	}

	//Date -> LocalDate
	public static LocalDate asLocalDate(Date date) {
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
	}

	//Date -> LocalDateTime
	public static LocalDateTime asLocalDateTime(Date date) {
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
	}

	//millis -> LocalDateTime
	public static LocalDateTime asLocalDateTime(Long millis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(millis);
		Date date = calendar.getTime();
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
	}

	public static Date getFromMillis(Long millis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(millis);
		return calendar.getTime();
	}

	public static Date add(Date date, Long millis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(date.getTime() + millis);
		return calendar.getTime();
	}

	private static Calendar getCal(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal;
	}

	public static String format(String format, Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}
	
	public static Date formatDate(String format, String date) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.parse(date);
	}

	public static String format(Date date, String format) {
		return format(format, date);
	}

	public static Date parse(String format, String dateStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);

		try {
			return sdf.parse(dateStr);
		} catch (ParseException var4) {
			var4.printStackTrace();
			return null;
		}
	}


	public static Date getBeginOfDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(date.getTime());
		cal.set(11, 0);
		cal.set(12, 0);
		cal.set(13, 0);
		cal.set(14, 0);
		return cal.getTime();
	}

	public static Date getEndOfDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getBeginOfDay(date));
		cal.add(5, 1);
		cal.add(14, -1);
		return cal.getTime();
	}

	public static Date getBeginOfWeek(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int weekIndex = cal.get(7);
		if (weekIndex == 1) {
			weekIndex = 7;
		} else {
			--weekIndex;
		}

		cal.add(5, (weekIndex - 1) * -1);
		return getBeginOfDay(cal.getTime());
	}

	public static Date getEndOfWeek(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getBeginOfWeek(date));
		cal.add(5, 6);
		return getEndOfDay(cal.getTime());
	}

	public static Date getBeginOfMonth(Date date) {
		Calendar cal = getCal(date);
		cal.set(5, 1);
		cal.set(11, 0);
		cal.set(12, 0);
		cal.set(13, 0);
		cal.set(14, 0);
		return getBeginOfDay(cal.getTime());
	}

	public static Date getEndOfMonth(Date date) {
		Calendar cal = getCal(date);
		cal.add(2, 1);
		Date nextMonth = getBeginOfMonth(cal.getTime());
		long milliSec = nextMonth.getTime() - 1L;
		return new Date(milliSec);
	}

	public static Date getBeingOfYear(Date date) {
		Calendar cal = getCal(date);
		int year = cal.get(1);
		return parse("yyyy-MM-dd HH:mm:ss.SSS", year + "-01-01 00:00:00.000");
	}

	public static Date getEndOfYear(Date date) {
		Calendar cal = getCal(date);
		int year = cal.get(1);
		return parse("yyyy-MM-dd HH:mm:ss.SSS", year + "-12-31 23:59:59.999");
	}

	public static Date add(Date date, int field, int amount) {
		Calendar cal = getCal(date);
		cal.add(field, amount);
		return cal.getTime();
	}

	public static Date dayOfLastYear(Date date) {
		Calendar cal = getCal(date);
		cal.add(1, -1);
		return getBeginOfDay(cal.getTime());
	}

	public static Date dayOfLastMonth(Date date) {
		Calendar cal = getCal(date);
		cal.add(2, -1);
		return getBeginOfDay(cal.getTime());
	}

	public static String constellation(Date date) {
		if (date == null) {
			return null;
		} else {
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			return constellation(cal.get(2), cal.get(5));
		}
	}

	public static String constellation(int month, int day) {
		String constellation = "";
		if (month == 1 && day >= 20 || month == 2 && day <= 18) {
			constellation = "水瓶座";
		}

		if (month == 2 && day >= 19 || month == 3 && day <= 20) {
			constellation = "双鱼座";
		}

		if (month == 3 && day >= 21 || month == 4 && day <= 19) {
			constellation = "白羊座";
		}

		if (month == 4 && day >= 20 || month == 5 && day <= 20) {
			constellation = "金牛座";
		}

		if (month == 5 && day >= 21 || month == 6 && day <= 21) {
			constellation = "双子座";
		}

		if (month == 6 && day >= 22 || month == 7 && day <= 22) {
			constellation = "巨蟹座";
		}

		if (month == 7 && day >= 23 || month == 8 && day <= 22) {
			constellation = "狮子座";
		}

		if (month == 8 && day >= 23 || month == 9 && day <= 22) {
			constellation = "处女座";
		}

		if (month == 9 && day >= 23 || month == 10 && day <= 23) {
			constellation = "天秤座";
		}

		if (month == 10 && day >= 24 || month == 11 && day <= 22) {
			constellation = "天蝎座";
		}

		if (month == 11 && day >= 23 || month == 12 && day <= 21) {
			constellation = "射手座";
		}

		if (month == 12 && day >= 22 || month == 1 && day <= 19) {
			constellation = "摩羯座";
		}

		return constellation;
	}
	public static Date ObjectZDate(Object object) {
		Date newDate=null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
			newDate = sdf.parse(object.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return newDate;  	
	} 

	/**
	 * 	两个时间相差分钟
	 * @param begin
	 * @param end
	 * @return
	 */
	public static String timeDifference(Date begin,Date end) {
		long between = (end.getTime() - begin.getTime());
		long day = between / (24 * 60 * 60 * 1000);
		long hour = (between / (60 * 60 * 1000) - day * 24);
		long min = ((between / (60 * 1000)) - day * 24 * 60 - hour * 60);
		long s = (between / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
		System.out.println(day + "天" + hour + "小时" + min + "分" + s + "秒");
		String ret = "";
		if(min == 0) {
			ret = s+"秒被抢光";
		}else {
			if(s == 0) {
				ret = min+"分钟被抢光";
			}else {
				ret = min+"分"+s+"秒被抢光";
			}
		}
		return ret;
	}


	/**
	 * 	比较版本号的大小,前者大则返回一个正数,后者大返回一个负数,相等则返回0
	 * @param version1
	 * @param version2
	 * @return
	 */
	public static int compareVersion(String version1, String version2) {
		String[] s1 = version1.split("\\."); //通过\\将.进行转义
		String[] s2 = version2.split("\\.");
		int len1 = s1.length;
		int len2 = s2.length;
		int i, j;
		for (i = 0, j = 0; i < len1 && j < len2; i++, j++) {
			if (Integer.parseInt(s1[i]) > Integer.parseInt(s2[j])) {
				return 1;
			} else if (Integer.parseInt(s1[i]) < Integer.parseInt(s2[j])) {
				return -1;
			}
		}
		while (i < len1) {
			if (Integer.parseInt(s1[i]) != 0) {
				return 1;
			}
			i++;
		}
		while (j < len2) {
			if (Integer.parseInt(s2[j]) != 0) {
				return -1;
			}
			j++;
		}
		return 0;
	}

	/**
	 * 获取当前日期是星期几<br>
	 * 
	 * @param date
	 * @return 当前日期是星期几
	 */
	public static String getWeekOfDateChinese(Date date) {
		String[] weekDays = { "星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return weekDays[w];
	}
	
	public static int getWeekOfDateChineseInteger() {
		int[] weekDays = { 7, 1, 2, 3, 4, 5, 6 };
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return weekDays[w];
	}

	/**
	 * 	获取两个日期相差的分钟
	 * @param begTime		
	 * @param endTime		
	 * @return
	 */
	public static Long timeDifferMinute(Date begTime,Date endTime) {
		long c = 0L;
		try {
			c = Math.abs( begTime.getTime() - endTime.getTime()) / (1000 *60);
		} catch (Exception e) {
			e.printStackTrace();
			return c;
		}
		return c;

	}

	/**
	 * 	获取两个日期相差的小时
	 * @param begTime		
	 * @param endTime		
	 * @return
	 */
	public static Long timeDifferHour(Date begTime,Date endTime) {
		long c = 0L;
		try {
			c = Math.abs( begTime.getTime() - endTime.getTime()) / (1000 * 60 * 60);
		} catch (Exception e) {
			e.printStackTrace();
			return c;
		}
		return c;
	}
	
	/**
	 * 	获取两个日期相差的秒数
	 * @param begTime		
	 * @param endTime		
	 * @return
	 */
	public static Long timeDifferSecond(Date begTime,Date endTime) {
		long c = 0L;
		try {
			c = (begTime.getTime() - endTime.getTime()) / (1000);
		} catch (Exception e) {
			e.printStackTrace();
			return c;
		}
		return c;
	}
	
	/**
	 * 	两个时间相差的天数
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int differentDaysByMillisecond(Date date1,Date date2)	{
		int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600*24));
		return days;
	}

	@SuppressWarnings("deprecation")
	public static boolean isNightOrder(Date begTime,Date endTime) {
		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			Date sd1=df.parse(df.format(begTime));
			Date sd2=df.parse( df.format(endTime));
			if (sd2.after(sd1)){
				return true;
			}
			int b = begTime.getHours();
			int e = endTime.getHours();
			return (b < 7 || b > 21) || (e < 7 || e > 21);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;

	}

	/**
	 * 获取本周的第一天
	 * @return
	 */
	public static String getWeekStart(){
		Calendar cal=Calendar.getInstance();
		cal.add(Calendar.WEEK_OF_MONTH, 0);
		cal.set(Calendar.DAY_OF_WEEK, 2);
		Date time=cal.getTime();
		return new SimpleDateFormat("yyyyMMdd").format(time);
	}
	/**
	 * 获取本周的最后一天
	 * @return
	 */
	public static String getWeekEnd(){
		Calendar cal=Calendar.getInstance();
		cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
		cal.add(Calendar.DAY_OF_WEEK, 1);
		Date time=cal.getTime();
		return new SimpleDateFormat("yyyyMMdd").format(time);
	}
	
	/***
	 * 判断是否ios审核版本
	 * @param apiVersion 实际请求版本号
	 * @param dbVersion 线上版本号
	 * @return
	 */
	public static Boolean isReviewWithiOS(String apiVersion, String dbVersion) {
		int i = compareVersion(apiVersion, dbVersion);
		if (i > 0){
			return true;
		}
		return false;
	}
	
	
	public static void main(String[] args) {
		
	}
}
